<?php
declare (strict_types=1);

namespace app\listener;

use app\common\job\SubsidySettle;
use app\common\model\Consulting;
use app\common\model\ConsultingMessage;
use app\common\model\ConsultingQuestion;
use app\common\model\ConsultingServer;
use app\common\model\ConsultingSubsidy;
use app\common\model\Trade;
use app\index\dao\ConsultingSubsidyDao;
use app\index\service\MessageSendService;
use ShidianUtil\Utils\TimeUtil;
use think\facade\Queue;
use think\model\Collection;

class FreeConsultingServerStart
{
    /**
     * 免费服务生效 事件监听处理
     *
     * @return void
     */
    public function handle($params)
    {
        $consulting = $params['consulting'] ?? null;
        $server = $params['server'] ?? null;
        $questionId = $consulting['questionId'];

        if (is_null($consulting) || is_null($server)) {
            // TODO 记录错误日志

            return;
        }

        // 只能激活免费咨询
        if ($server->serverType != ConsultingServer::FREE) {
            return;
        }

        // 随机匹配 指定律师 律师抢单 才享受免费咨询和补贴
        if (!in_array($consulting->initMatchType, [0, 1, 2])) {
            return;
        }

        // 没有提问不能激活免费咨询服务
        if (!is_id($questionId)) {
            return;
        }

        // 服务生效

        // 生效时间
        $now = time();
        $sTime = TimeUtil::stamp(TimeUtil::DAY, $now);
        $eTime = TimeUtil::stamp(TimeUtil::DAY, $sTime, false);
        // 享受服务的用户ID
        $memberId = $consulting->memberId;
        // 每日赠送免费咨询次数
        $maxTimes = $server->maxTimes;

        // 查询问题
        $question = ConsultingQuestion::where('id', $questionId)->find();
        if (!$question) {
            return;
        }

        // 同问题其他咨询激活了免费咨询服务，本咨询也同样激活
        if ($question->freeConsultingServerId != 0) {
            $this->activeServer($consulting, $server, $sTime, $eTime, null);
            return;
        }

        // 查询今天是否还有剩余的免费咨询次数
        $count = ConsultingQuestion::where('memberId', $memberId)
            ->where('freeConsultingServerId', '<>', 0)
            ->timeRange($sTime, $eTime, 'freeConsultingServerTime', 'freeConsultingServerTime')
            ->count();
        if ($count < $maxTimes) {
            // 还有免费咨询次数，激活免费咨询服务
            $this->activeServer($consulting, $server, $sTime, $eTime, $question);
            return;
        }
    }

    // 激活服务
    private function activeServer(Consulting $consulting, ConsultingServer $server, $sTime, $eTime, ?ConsultingQuestion $question)
    {
        // 享受服务的用户ID
        $memberId = $consulting->memberId;

        // 更新提问
        if ($question) {
            $question->freeConsultingServerId = $server->id;
            $question->freeConsultingServerTime = $sTime;
            $question->save();
        }

        // 更新咨询的活动时间
        $lastActiveTime = time() + 24 * 3600;
        $consulting->updateActiveTime($lastActiveTime);

        // ************** 聊天时长和次数 ******************

        // 给对应的咨询添加聊天时长和次数
        $this->handleTimeAndNum($consulting, $server);

        // 插入补贴
        $this->insertSubsidy($consulting, $server, $memberId, $sTime, $eTime);
    }

    /**
     * 插入补贴
     * @param ConsultingServer $server
     * @param int $memberId
     * @param $sTime
     * @param $eTime
     * @param Consulting $consulting
     * @return void
     */
    private function insertSubsidy(Consulting $consulting, ConsultingServer $server, int $memberId, $sTime, $eTime): void
    {
        if ($server->subsidy <= 0) {
            return;
        }

        // 每天只补贴一个人一次
        $subsidy = ConsultingSubsidy::where('memberId', $memberId)
            ->timeRange($sTime, $eTime, 'created', 'created')
            ->find();
        if ($subsidy) {
            return;
        }

        $subsidyParams = [
            'memberId' => $consulting->memberId,
            'serverId' => $server->id,
            'questionId' => $consulting->questionId,
            'consultingId' => $consulting->id,
            'lawyerId' => $consulting->lawyerId,
            'subsidy' => $server->subsidy,
            'settleStatus' => Trade::UNSETTLED,
        ];
        $subsidy = $this->getConsultingSubsidyDao()->insertActive($subsidyParams);

        // 添加补贴结算任务
        $job_data = ['id' => $subsidy->id];
        Queue::later(86400, SubsidySettle::class, $job_data);
    }

    /**
     * 聊天时长和次数
     * @param Consulting $consulting
     * @param ConsultingServer $server
     * @return void
     */
    private function handleTimeAndNum(Consulting $consulting, ConsultingServer $server)
    {
        // 查询同问题下全部咨询，都加次数

        if (is_id($consulting->questionId)) {
            $consultings = Consulting::where('questionId', $consulting->questionId)
                ->where('freeNum', 0)
                ->select();
        } else {
            $consultings = Collection::make([$consulting]);
        }

        // 对应的咨询添加追问次数
        $consultings->each(function (Consulting $consulting) use ($server) {

            // 赠送次数
            $consulting->questionsNum += $server->questionsNum;
            $consulting->freeNum += $server->questionsNum;
            $consulting->questionsNumRemind = 0;
            $consulting->save();

            // 发消息 获得免费次数
            $content = [
                'templates' => [
                    ['type' => 'text', 'red' => '102', 'text' => '律师已接单，当前可用追问次数为',],
                    ['type' => 'text', 'red' => '101', 'text' => $consulting->questionsNum . '次',],
                    ['type' => 'text', 'red' => '102', 'text' => '，您的每次提问即算一次追问，请留意追问次数，妥善提问。',],
                ],
            ];
            $this->getMessageSendService()->sendSystemMessage($consulting, $consulting->memberId, ConsultingMessage::SYSTEM, $content);
        });


    }

    private function getMessageSendService(): MessageSendService
    {
        return app(MessageSendService::class);
    }

    private function getConsultingSubsidyDao(): ConsultingSubsidyDao
    {
        return app(ConsultingSubsidyDao::class);
    }

}
